
// 声明模块
pub mod lexer;
pub mod token;
pub mod parser;
pub mod ast;
pub mod repl;
pub mod object;
pub mod evaluator;

#[cfg(test)]
mod tests {
    use std::any::Any;
    use core::panic;
    use crate::ast::{BlockStatement, BoolLiteral, Expression, ExpressionStatement, FunctionLiteral, Identifier, IfExpression, InfixExpression, IntegerLiteral, LetStatement, Node, PrefixExpression, Program, ReturnStatement, Statement,CallExpression};
    use crate::token::{Token, TokenType};
    // use crate::lexer::{init_lexer};
    use crate::lexer::{self, Lexer};
    use crate::parser::{self, Parser};
    use std::sync::Arc;
    // use tracing::{info, instrument};
    // use tracing_subscriber;

    #[test]
    fn test_next_token(){
        let input = "let five = 5;";
        let tests = &[
            (TokenType::LET, "let"),
            (TokenType::IDENT, "five"),
            (TokenType::ASSIGN, "="),
            (TokenType::INT, "5"),
            (TokenType::SEMICOLON, ";"),
        ];
        // let mut lexer = init_lexer(input);
        let mut lexer = Lexer::new(input.to_string());
        for test in tests{
            let tok = lexer.next_token();
            if tok.literal != test.1 {
                panic!("Expected literal '{}', got '{}'", test.1, tok.literal);
            }

            match tok.token_type {
                TokenType::LET => { 
                    match test.0 {
                        TokenType::LET => {},
                        _ => {panic!("Expected literal '{}', got '{}'", "LET", tok.token_type.to_string())},
                    }
                },
                TokenType::IDENT => { 
                     match test.0 {
                        TokenType::IDENT => {},
                        _ => {panic!("Expected literal '{}', got '{}'", "IDENT", tok.token_type.to_string())},
                    }
                },
                TokenType::ASSIGN => { 
                     match test.0 {
                        TokenType::ASSIGN => {},
                        _ => {panic!("Expected literal '{}', got '{}'", "ASSIGN", tok.token_type.to_string())},
                    }
                },
                TokenType::INT => { 
                     match test.0 {
                        TokenType::INT => {},
                        _ => {panic!("Expected literal '{}', got '{}'", "INT", tok.token_type.to_string())},
                    }
                },
                TokenType::SEMICOLON => { 
                     match test.0 {
                        TokenType::SEMICOLON => {},
                        _ => {panic!("Expected literal '{}', got '{}'", "SEMICOLON", tok.token_type.to_string())},
                    }
                },
                _ => {print!("congradulations! test passed!!!")},
            }
        }

    }

    fn check_parser_errors(p: &Parser){
        let errors = p.get_errors();
        if errors.len() == 0 {
            return;
        }
        // panic!("Parser has {} errors", errors.len());
        eprint!("Parser has {} errors", errors.len());
        for e in errors {
            eprintln!("parser error: {}", e);
        }
    }

    // fn test_let_statement_common(statement: &dyn Statement, ident: &dyn Any)->bool{
    //     if statement.token_literal() != "let"{
    //         eprintln!("statement is not a let statement");
    //         return false;
    //     }
    //     let l_stmt = statement.as_any().downcast_ref::<LetStatement>().unwrap();
    //     // l_stmt.name.as_ref().unwrap().value == ident.downcast_ref::<String>().unwrap()
    //     if ident.is::<bool>() || ident.is::<i32>() || ident.is::<i64>() || ident.is::<String>() {
    //         if &l_stmt.name.as_ref().unwrap().value != ident.downcast_ref::<String>().unwrap(){
    //             return false;
    //         }
    //         // assert_eq!(&l_stmt.name.as_ref().unwrap().value, ident.downcast_ref::<String>().unwrap());
    //         // eprintln!("实际类型是: BoolLiteral");
    //     // } else if ident.is::<IntegerLiteral>() {
    //     //     // eprintln!("实际类型是: IntegerLiteral");
    //     // } else if ident.is::<Identifier>() {
    //     //     // eprintln!("实际类型是: Identifier");
    //     } else {
    //         eprintln!("未知的表达式类型");
    //         return false;
    //     }
    //     true
    //     // unimplemented!()
    // }

    #[test]
    fn test_let_statement(){

        struct LetTest{
            input: String,
            expected_identifier: String,
            expected_value: Arc<dyn Any>,
        }
        let tests = vec![
            LetTest{
                input: "let x = 5;".to_string(),
                expected_identifier: "x".to_string(),
                expected_value: Arc::new(5),
            },
            LetTest{
                input: "let y = true;".to_string(),
                expected_identifier: "y".to_string(),
                expected_value: Arc::new(true),
            },
            LetTest{
                input: "let foobar = y;".to_string(),
                expected_identifier: "foobar".to_string(),
                expected_value: Arc::new("y"),
            },
        ];
        for test  in tests{
    //         let input = "
    // let aaaa = 5;
    // let y = 10;
    // let z = 83333;
    // ";
            // let lexer = Lexer::new(input.to_string());
            let lexer = Lexer::new(test.input);
            let mut parser = Parser::new(lexer);
            let program = parser.parse_program();
            check_parser_errors(&parser);
            if program.statements.len() != 1{
                panic!("program.Statements does not contain 1 statements. got={}", program.statements.len());
            }
            if let Some(stmt) = program.statements.get(0).unwrap().as_any().downcast_ref::<LetStatement>(){
                assert_eq!(stmt.name.as_ref().unwrap().value, test.expected_identifier);
                let val = stmt.value.as_ref().unwrap();
                eprintln!("exp: {}", val.to_string());
                if !test_literal_expression(&**val, &*test.expected_value){
                    panic!("value is not a literal expression");
                }
            }else{
                panic!("stmt is not a LetStatement");
            }
            // if !test_let_statement_common(stmt.as_ref(), Arc::new(test.expected_identifier).as_ref()){
            //     // paniic!("");
            //     return;
            // }


            // if !test_let_sta
            // let tests = ["x","y","foobar"];
            // let mut i = 0;
            // for t in tests {
            //     if let Some(s) = program.statements.get(i){
            //         test_let_stat( s.clone(), t.to_string());
            //     }else{
            //         panic!("program.statements.get(i) is None");
            //     }
            //     i += 1;
            // }
            // println!("congratulation! test passed!");
        }
    }

    fn test_let_stat(s: Arc<dyn Statement>, name: String) -> bool 
    {
        if s.as_ref().token_literal() != "let" {
            panic!("s.TokenLiteral want: {}, got: {}", "let", s.as_ref().token_literal());
            // return false;
        }
        if let Some(let_stmt_box) = s.as_ref().as_any().downcast_ref::<LetStatement>() {
            let let_stmt: &LetStatement = let_stmt_box;
            println!("{}", let_stmt.token.token_type.to_string());
            if let Some(ref stmt_name) = let_stmt.name {
                stmt_name.value == name
            } else {
                false
            }
        } else {
            println!("s is Not a LetStatement");
            false
        }

    }

    #[test]
    fn test_return_statement(){
        let input = "
        return 123;
return 1;
return add(15);
";
        let lexer = Lexer::new(input.to_string());
        let mut parser = Parser::new(lexer);
        let program = parser.parse_program();
        check_parser_errors(&parser);
        if program.statements.len() != 3{
            panic!("program.Statements does not contain 3 statements. got={}", program.statements.len());
        }
        for t in program.statements {
            if t.as_ref().token_literal() != "return" {
                panic!("s.TokenLiteral want: {}, got: {}", "return", t.as_ref().token_literal());
            }
            // todo: &t是&Box类型，为何能直接转换成&dyn Any ?
            if let Some(stmt) = t.as_ref().as_any().downcast_ref::<ReturnStatement>() {
                println!("{}", stmt.token.token_type.to_string());
            } else {
                panic!("stmt is not a ReturnStatement");
            }

        }
        println!("congratulation! test passed!");
    }


    #[test]
    fn test_string(){
        let program = Program{
            statements: vec![
                Arc::new(LetStatement{
                    token: Token{token_type: TokenType::LET, literal: "let".to_string()} ,
                    name: Some(Identifier{
                        token: Token{token_type: TokenType::IDENT, literal: "myVar".to_string()},
                        value: "myVar".to_string(),
                    }) ,
                    value: Some(Arc::new(Identifier{
                        token: Token{token_type: TokenType::IDENT, literal: "anotherVar".to_string()},
                        value: "anotherVar".to_string(),
                    })),
                })
            ]
        };
        assert_eq!(program.to_string(), "let myVar = anotherVar;".to_string());
    }


    #[test]
    fn test_identifier_expression(){
        let input = "foobar;";
        let lexer = Lexer::new(input.to_string());
        let mut parser = Parser::new(lexer);
        let program = parser.parse_program();
        check_parser_errors(&parser);
        if program.statements.len() != 1{
            panic!("program.Statements does not contain 1 statements. got={}", program.statements.len());
        }
        if let Some(stmt) = program.statements.get(0).unwrap().as_any().downcast_ref::<ExpressionStatement>(){
            if let Some(ident) = stmt.expression.as_ref(){
                if let Some(id) = ident.as_any().downcast_ref::<Identifier>(){
                    assert_eq!(id.value, "foobar".to_string());
                    assert_eq!(id.token_literal(), "foobar".to_string());
                }else{
                    panic!("id is null");
                }
                // unwrap().as_any().downcast_ref::<Identifier>(){
                // assert_eq!(ident.value, "foobar".to_string());
                // assert_eq!(ident.token_literal(), "foobar".to_string());
            }else{
                //这里提示没初始化，需要检查parser/parser.rs中的prefix_parse_fns有没有执行到
                panic!("identifier has not been initialized");
            }
        }else{
            panic!("program.statements.get(0) is not ExpressionStatement");
        }

        
    }

    #[test]
    fn test_integer_literal_expression(){
        let input = "5;";
        let lexer = Lexer::new(input.to_string());
        let mut parser = Parser::new(lexer);
        let program = parser.parse_program();
        check_parser_errors(&parser);
        if program.statements.len() != 1{
            panic!("program.Statements does not contain 1 statements. got={}", program.statements.len());
        }
        if let Some(stmt) = program.statements.get(0).unwrap().as_any().downcast_ref::<ExpressionStatement>(){
            eprintln!("literal={}", stmt.token.literal);
            if let Some(integer) = stmt.expression.as_ref(){
                if let Some(inte) = integer.as_any().downcast_ref::<IntegerLiteral>(){
                    assert_eq!(inte.value, 5);
                    assert_eq!(inte.token_literal(), "5");
                }else{
                    panic!("stmt is not a IntegerLiteral");
                }
            }else{
                //这里提示没初始化，需要检查parser/parser.rs中的prefix_parse_fns有没有执行到
                panic!("integer has not been initialized");
            }
        }else{
            panic!("program.statements.get(0) is not ExpressionStatement");
        }
    }

    struct Prefix{
        input: String,
        operator: String,
        integer_value: i64,
    }
    
    //测试小套件begin
    fn test_integer_literal(il: &dyn Expression, value: i64) -> bool{
        if let Some(integ) = il.as_any().downcast_ref::<IntegerLiteral>(){
            if integ.value != value{
                eprintln!("integ.value want: {}, got: {}", value, integ.value);
                false
            }else{
                // 假设 integ 是 ast::IntegerLiteral 类型，value 是一个整数类型 (例如 i64)
                // 并且 integ.token_literal() 返回 String 类型
                if integ.token_literal() != format!("{}", value) {
                    // 在 Rust 的测试函数中，通常使用 panic! 来报告错误并使测试失败
                    eprintln!("integ.token_literal not {}. got={}", value, integ.token_literal());
                    // 如果是在非测试函数中，你可能需要返回一个 Result 类型来表示错误
                    false
                }else{
                    true
                }
            }
        }else{
            eprintln!("il is not a IntegerLiteral");
            false
        }
    }
    //测试小套件end

    fn test_identifier(exp: &dyn Expression, value: String) -> bool{
        if let Some(ident) = exp.as_any().downcast_ref::<Identifier>(){
            assert_eq!(ident.value, value);
            assert_eq!(ident.token_literal(), value);
            true
        }else{
            eprintln!("exp is not Identifier, got {}", exp.token_literal());
            false
        }
    }
    

    #[test]
    fn test_parsing_prefix_expressions(){
        let tests = vec![
            Prefix{
                input: "-15".to_string(),
                operator: "-".to_string(),
                integer_value: 15,
            },
            Prefix{
                input: "!5".to_string(),
                operator: "!".to_string(),
                integer_value: 5,
            },
        ];   
        for test in tests{
            let l = Lexer::new(test.input);
            let mut p = Parser::new(l);
            let program = p.parse_program();
            check_parser_errors(&p);
            if program.statements.len() != 1{
                panic!("program.Statements does not contain 1 statements. got={}", program.statements.len());
            }
            if let Some(stmt) = program.statements.get(0).unwrap().as_any().downcast_ref::<ExpressionStatement>(){
                if let Some(exp) = stmt.expression.as_ref(){ 
                    if let Some(prefix) = exp.as_any().downcast_ref::<PrefixExpression>(){
                        assert_eq!(prefix.operator, test.operator);
                        // assert_eq!(prefix.right.as_ref().unwrap().to_string(), test.integer_value.to_string())
                        if !test_integer_literal(prefix.right.as_ref().unwrap().as_ref(),  test.integer_value){
                            panic!("test_integer_literal failed");
                        }
                    }else{
                        panic!("exp is not PrefixExpression");
                    }
                }else{
                    panic!("prefix expression has not been initialized");
                }
            }else{
                panic!("program.statements.get(0) is not ExpressionStatement");
            }

        }
    }

    
    #[test]
    fn test_parsing_infix_expressions(){  
        struct Infix{
            input: String,
            left: Arc<dyn Any>,
            operator: String,
            right: Arc<dyn Any>,
        }
        let tests = vec![
            Infix{
                input: "true == true".to_string(),
                left: Arc::new(true),
                operator: "==".to_string(),
                right: Arc::new(true),
            },
            Infix{
                input: "true != false".to_string(),
                left: Arc::new(true),
                operator: "!=".to_string(),
                right: Arc::new(false),
            },
            Infix{
                input: "false == false".to_string(),
                left: Arc::new(false),
                operator: "==".to_string(),
                right: Arc::new(false),
            },
        ];
        for test in tests{ 
            let lexer = Lexer::new(test.input);
            let program = Parser::new(lexer).parse_program();
            let stmt = program.statements.get(0).unwrap();
            if let Some(exp) = (&**stmt).as_any().downcast_ref::<ExpressionStatement>(){
                if !test_infix_expression(&**exp.expression.as_ref().unwrap(), test.left.as_ref(), test.operator, test.right.as_ref()){
                    panic!("test_infix_expression failed");
                }
            }else{
                    panic!("exp is not ExpressionStatement");
                }
            
        }
    }

    struct Infix{
        input: String,
        left: i64,
        operator: String,
        right: i64,
    }

    #[test]
    fn test_expression_statement(){
        let input = "Alice*Bob".to_string();
        let lexer = Lexer::new(input);
        let mut parser = Parser::new(lexer);
        let program = parser.parse_program();
        for statements  in program.statements{
            if let Some(stmt) =  statements.as_any().downcast_ref::<ExpressionStatement>(){
                if let Some(exp) = stmt.expression.as_ref(){
                    let left: Arc<dyn Any> = Arc::new("Alice".to_string());
                    let right: Arc<dyn Any> = Arc::new("Bob".to_string());
                    if !test_infix_expression(&**exp, left.as_ref(), "*".to_string(), right.as_ref()){
                        panic!("expression statement parse error");
                    }
                }
            }else{
                panic!("statment is not a expression statement");
            }
        }
    }

    /**
     * 前缀表达式测试公用函数
     */
    fn test_prefix_expression(exp: &dyn Expression,operator: String, right: &dyn Any)->bool{
        if let Some(prfix) = exp.as_any().downcast_ref::<PrefixExpression>(){
            if !test_literal_expression(&**prfix.right.as_ref().unwrap(), right){
                panic!("test_literal_expression failed");
            }
            assert_eq!(prfix.operator, operator);
            true
        }else{
            false
        }
    }

    /**
     * 中缀表达式测试公用函数
     */
    fn test_infix_expression(exp: &dyn Expression, left: &dyn Any, operator: String, right: &dyn Any)->bool{
        if let Some(infix) = exp.as_any().downcast_ref::<InfixExpression>(){
            let mut b_result = false;
            if let Some(lf) = infix.left.clone(){
                // eprintln!("lf.as_ref()={:?},lf.as_ref()={:?}", lf.as_ref(), left);
                b_result = test_literal_expression(lf.as_ref(), left);
                // eprintln!("b_result 1 = {}", b_result);
            }else{
                eprintln!("left expected InfixExpression error");
                return false;
            }
            assert_eq!(infix.operator, operator);
            if let Some(rt) = infix.right.clone(){
                b_result = b_result && test_literal_expression(rt.as_ref(), right);
                // eprintln!("b_result 2 = {}", b_result);
            }else{
                eprintln!("left expected InfixExpression error");
                return false;
            }
            // eprintln!("b_result 3 = {}", b_result);
            b_result
        }else{
            eprintln!("exp expected InfixExpression, got {}", exp.token_literal());
            false
        }
    }
    struct Operator{
        input: String,
        expected: String,
    }
    #[test]
    fn test_operator_predence_parsing(){
        let tests = vec![
            Operator{
                input: "a+add(b*c)+d".to_string(),
                expected: "(a+add((b*c)))+d".to_string(),
            },
            Operator{
                input: "add(a,b,1,2*3,4+5,add(6,7*8))".to_string(),
                expected: "add(a,b,1,(2*3),(4+5),add(6,(7*8)))".to_string(),
            },
            Operator{
                input: "add(a+b+c*d/f+g)".to_string(),
                expected: "add((a+b)+((c*d)/f)+g)".to_string(),
            },
            Operator{
                input: "2/(5+5)".to_string(),
                expected: "(2/(5+5))".to_string(),
            },
            Operator{
                input: "-(5+5)".to_string(),
                expected: "(-(5+5))".to_string(),
            },
            Operator{
                input: "!(true==true)".to_string(),
                expected: "(!(true==true))".to_string(),
            },
        ];
        for test in tests{
            let l = Lexer::new(test.input);
            let mut p = Parser::new(l);
            let program = p.parse_program();
            check_parser_errors(&p);
            assert_eq!(test.expected, program.to_string());
        }
    }
    
    

    fn test_bool_literal(exp: &dyn Expression, value: bool)->bool{
        if let Some(bo) = exp.as_any().downcast_ref::<BoolLiteral>(){
            assert_eq!(bo.value, value);
            assert_eq!(bo.token_literal(), value.to_string());
            true
        }else{
            eprintln!("exp is not BoolLiteral, got {}", exp.token_literal());
            false
        }
    }

    fn test_literal_expression(exp: &dyn Expression, expected: &dyn Any)->bool{
        if let Some(e) = expected.downcast_ref::<i64>(){
            eprintln!("a = {}", e);
            test_integer_literal(exp, e.clone())
        }else if let Some(e) = expected.downcast_ref::<i32>(){
            eprintln!("aa = {}", e);
            test_integer_literal(exp, (*e) as i64)
        } else if let Some(e) = expected.downcast_ref::<String>(){
            eprintln!("b = {}", e);
            test_identifier(exp, e.clone())
        }else if let Some(e) = expected.downcast_ref::<&str>(){
            eprintln!("c = {}", e);
            test_identifier(exp, e.to_string())
        }else if let Some(e) = expected.downcast_ref::<bool>(){
            eprintln!("d = {}", e);
            test_bool_literal(exp, e.clone())
        }
          else{
            eprintln!("e = {}", exp.to_string());
            // eprintln!("expected value is null");
            false
        }
    }


    #[test]
    fn test_bool_expression(){
        let input = "true;";
        let lexer = Lexer::new(input.to_string());
        let mut parser = Parser::new(lexer);
        let program = parser.parse_program();
        check_parser_errors(&parser);
        if program.statements.len() != 1{
            panic!("program.Statements does not contain 1 statements. got={}", program.statements.len());
        }
        if let Some(stmt) = program.statements.get(0).unwrap().as_any().downcast_ref::<ExpressionStatement>(){
            if let Some(exp) = stmt.expression.as_ref(){
                // let any_ref = exp.as_any();
                // eprintln!("type id is {:?}", any_ref.type_id());
                // // 尝试识别具体类型
                // if any_ref.is::<BoolLiteral>() {
                //     eprintln!("实际类型是: BoolLiteral");
                // } else if any_ref.is::<IntegerLiteral>() {
                //     eprintln!("实际类型是: IntegerLiteral");
                // } else if any_ref.is::<Identifier>() {
                //     eprintln!("实际类型是: Identifier");
                // } else {
                //     eprintln!("未知的表达式类型");
                // }
                
                if let Some(bl) = exp.as_any().downcast_ref::<BoolLiteral>(){
                    assert_eq!(bl.value, true);
                    assert_eq!(bl.token_literal(), "true".to_string());
                }else{
                    
                    panic!("true literal is null");
                }
            }else{
                //这里提示没初始化，需要检查parser/parser.rs中的prefix_parse_fns有没有执行到
                panic!("identifier has not been initialized");
            }
        }else{
            panic!("program.statements.get(0) is not ExpressionStatement");
        }

        
    }

    #[test]
    fn test_if_else_expression(){
        let input = "if (x<y) {x} else {y}";
        let lexer = Lexer::new(input.to_string());
        let mut parser = Parser::new(lexer);
        let program = parser.parse_program();
        check_parser_errors(&parser);
        if program.statements.len() != 1{
            panic!("program.Statements does not contain 1 statements. got={}", program.statements.len());
        }

        if let Some(exp_stmt) = program.statements.get(0).unwrap().as_any().downcast_ref::<ExpressionStatement>(){
            if let Some(if_exp) = exp_stmt.expression.as_ref().unwrap().as_any().downcast_ref::<IfExpression>(){ 
                if let Some(cond) = if_exp.condition.as_ref(){
                    if !test_infix_expression(cond.as_ref(), Arc::new("x").as_ref(), "<".to_string(), Arc::new("y").as_ref()){
                        return;
                    }
                    eprintln!("if_exp.consequence.as_ref().unwrap().statements: {:?}, len: {}",if_exp.consequence.as_ref().unwrap().statements, if_exp.consequence.as_ref().unwrap().statements.len() );
                    if if_exp.consequence.as_ref().unwrap().statements.len() != 1{
                        panic!("consequence is not 1 statement");
                    }
                    eprintln!("token literal: {}", if_exp.token_literal());
                    // // 尝试识别具体类型
                    // if if_exp.consequence.as_ref().unwrap().as_any().is::<LetStatement>() {
                    //     eprintln!("实际类型是: BoolLiteral");
                    // } else if if_exp.consequence.as_ref().unwrap().as_any().is::<ReturnStatement>() {
                    //     eprintln!("实际类型是: ReturnStatement");
                    // }else if if_exp.consequence.as_ref().unwrap().as_any().is::<IntegerLiteral>() {
                    //     eprintln!("实际类型是: IntegerLiteral");
                    // } else if if_exp.consequence.as_ref().unwrap().as_any().is::<Identifier>() {
                    //     eprintln!("实际类型是: Identifier");
                    // }else if if_exp.consequence.as_ref().unwrap().as_any().is::<ExpressionStatement>(){
                    //     eprintln!("实际类型是: ExpressionStatement");
                    // } else if if_exp.consequence.as_ref().unwrap().as_any().is::<IfExpression>(){
                    //     eprintln!("实际类型是: IfExpression");
                    // }else if if_exp.consequence.as_ref().unwrap().as_any().is::<BlockStatement>(){
                    //     eprintln!("实际类型是: BlockStatement");
                    // }
                    
                    // else {
                    //     eprintln!("未知的表达式类型");
                    // }
                    if let Some(csq) = if_exp.consequence.as_ref().unwrap().statements.get(0).unwrap().as_any().downcast_ref::<ExpressionStatement>(){
                        if !test_identifier(&**csq.expression.as_ref().unwrap(), "x".to_string()){
                            eprintln!("if_exp.consequence={:?}",if_exp.consequence);
                            return;
                        }
                        // if let Some(alt) = if_exp.alternative.as_ref(){
                        //     panic!("alternative is null , got {:?}", alt);
                        // }
                    }else{
                        panic!("consequence is not ExpressionStatement");
                    }
                    
                    if let Some(alt) = if_exp.alternative.as_ref().unwrap().statements.get(0).unwrap().as_any().downcast_ref::<ExpressionStatement>(){
                        if !test_identifier(&**alt.expression.as_ref().unwrap(), "y".to_string()){
                            return;
                        }
                    }else{
                        panic!("consequence is not ExpressionStatement");
                    }

                }else{
                    panic!("condition is null");
                }
            }else{
                panic!("identifier has not been initialized");
            }
        }else{
            panic!("program.statements.get(0) is null");
        }
    }

    #[test]
    fn test_function_expression(){
        let input = "fn(x,y){x+y;}";
        let lexer = Lexer::new(input.to_string());
        let mut parser = Parser::new(lexer);
        check_parser_errors(&parser);
        let program = parser.parse_program();
        if program.statements.len() != 1{
            panic!("program.Statements does not contain 1 statements. got={}", program.statements.len());
        }
        if let Some(stmt) = program.statements.get(0).unwrap().as_ref().as_any().downcast_ref::<ExpressionStatement>(){
            if let Some(exp)= stmt.expression.as_ref().unwrap().as_any().downcast_ref::<FunctionLiteral>(){
                if exp.params.as_ref().unwrap().len() != 2{
                    panic!("exp.params expected 2, got {}", exp.params.as_ref().unwrap().len());
                }
                if !test_literal_expression(exp.params.as_ref().unwrap().get(0).unwrap(), Arc::new("x").as_ref()){
                    panic!("exp.params expected {}, got x", exp.params.as_ref().unwrap().get(0).unwrap().token_literal());
                }
                if !test_literal_expression(exp.params.as_ref().unwrap().get(1).unwrap(), Arc::new("y").as_ref()){
                    panic!("exp.params expected {}, got y", exp.params.as_ref().unwrap().get(0).unwrap().token_literal());
                }
                if exp.body.as_ref().unwrap().statements.len() != 1{
                    panic!("exp.body expected 1, got {}", exp.body.as_ref().unwrap().statements.len());
                }
                if let Some(bexp) = exp.body.as_ref().unwrap().statements.get(0).unwrap().as_any().downcast_ref::<ExpressionStatement>(){
                    if !test_infix_expression(&**bexp.expression.as_ref().unwrap(), Arc::new("x").as_ref(), "+".to_string(), Arc::new("y").as_ref()){
                        panic!("test_infix_expression failed");
                    }
                }else{
                    panic!("exp.body[0] is not an ExpressionStatement");
                }
            }else{
                panic!("expression is not FunctionLiteral");
            }
        }else{
            panic!("program.statements.get(0) is not ExpressionStatement");
        }
    }

    #[test]
    fn test_function_parameter_parsing(){
        struct Test{
            input: String,
            expected_parsms: Vec::<String>,
        }
        let tests = vec![
            Test{
                input: "fn(){}".to_string(),
                expected_parsms: vec![],
            },
            Test{
                input: "fn(x){}".to_string(),
                expected_parsms: vec!["x".to_string()],
            },
            Test{
                input: "fn(x,y,z){}".to_string(),
                expected_parsms: vec!["x".to_string(),"y".to_string(),"z".to_string()],
            },
        ];
        for test in tests{
            let lexer = Lexer::new(test.input);
            let mut parser = Parser::new(lexer);
            let program = parser.parse_program();
            check_parser_errors(&parser);
            if program.statements.len() != 1{
                panic!("program.Statements does not contain 1 statements. got={}", program.statements.len());
            }
            if let Some(stmt) = program.statements.get(0).unwrap().as_any().downcast_ref::<ExpressionStatement>(){
                if let Some(function) = stmt.expression.as_ref().unwrap().as_any().downcast_ref::<FunctionLiteral>(){
                    if function.params.as_ref().unwrap().len() != test.expected_parsms.len(){
                        panic!("length param wrong, expected {}, got {}", function.params.as_ref().unwrap().len() , test.expected_parsms.len());
                    }
                    for i in 0..test.expected_parsms.len(){
                        // let f = function.params.as_ref().unwrap().get(i);
                        if !test_literal_expression(function.params.as_ref().unwrap().get(i).unwrap(), test.expected_parsms.get(i).unwrap()){
                            panic!("test_literal_expression error");
                        }
                    }
                }else{
                    panic!("function is not a FunctionLiteral");
                }
            }else{
                panic!("program.statements[0] is not an ExpressionStatement");
            }
        }
    }

    #[test]
    fn test_call_expression_parsing(){
        let input = "add(1, 2*3, 4+5);";
        let lexer = Lexer::new(input.to_string());
        let mut parser = Parser::new(lexer);
        let program = parser.parse_program();
        check_parser_errors(&parser);
        if program.statements.len() != 1{
            panic!("program.Statements does not contain 1 statements. got={}", program.statements.len());
        }
        if let Some(stmt) = program.statements.get(0).unwrap().as_any().downcast_ref::<ExpressionStatement>(){
            if let Some(exp) = stmt.expression.as_ref().unwrap().as_any().downcast_ref::<CallExpression>(){
                if !test_identifier(exp.function.as_ref(), "add".to_string()){
                    panic!("exp.function is not an identifier");
                }
                if exp.arguments.len() != 3{
                    panic!("exp.arguments.len() expected 3, got {}", exp.arguments.len());
                }
                test_literal_expression(&**exp.arguments.get(0).unwrap(), Arc::new(1).as_ref());
                test_infix_expression(&**exp.arguments.get(1).unwrap(), Arc::new(2).as_ref(), "*".to_string(), Arc::new(3).as_ref());
                test_infix_expression(&**exp.arguments.get(2).unwrap(), Arc::new(4).as_ref(), "+".to_string(), Arc::new(5).as_ref());
            }else{
                panic!("expression is not CallExpression");
            }
        }else{
            panic!("program.statements[0] is not an ExpressionStatement");
        }
    }
}